using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BillsDomain
{
    public class Recurrence : IEquatable<Recurrence>
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification="Recurrence is immutable")]
        public static readonly Recurrence None = new Recurrence("None");

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Recurrence is immutable")]
        public static readonly Recurrence Monthly = new Recurrence("Monthly");

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Recurrence is immutable")]
        public static readonly Recurrence Biweekly = new Recurrence("Bi-weekly");

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Recurrence is immutable")]
        public static readonly Recurrence Weekly = new Recurrence("Weekly");

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Recurrence is immutable")]
        public static readonly Recurrence Bimonthly = new Recurrence("Bi-Monthly");

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Recurrence is immutable")]
        public static readonly Recurrence Unknown = new Recurrence("Unknown");

        private static IDictionary<string, Recurrence> AllRecurrences = new Dictionary<string, Recurrence>() { { None.Name, None }, { Bimonthly.Name, Bimonthly }, { Monthly.Name, Monthly }, { Biweekly.Name, Biweekly }, { Weekly.Name, Weekly }, { Unknown.Name, Unknown } };

        private Recurrence(string name)
        {
            this.Name = name;
        }

        public static Recurrence FindByName(string name)
        {
            try
            {
                return AllRecurrences[name];
            }
            catch (KeyNotFoundException)
            {
                return Unknown;
            }
        }

        public override string ToString()
        {
            return this.Name;
        }

        public string Name { get; private set; }

        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Recurrence);
        }

        public bool Equals(Recurrence other)
        {
            return (other == null ? false : IsEqualTo(other));
        }

        private bool IsEqualTo(Recurrence other)
        {
            return other == this || this.Name.Equals(other.Name);
        }
    }
}
